package com.ts.api.http.platform.biz;

import com.alibaba.fastjson.JSONObject;
import com.gitee.apanlh.util.algorithm.encrypt.AlgorithmPadding;
import com.gitee.apanlh.util.algorithm.encrypt.symmetric.AES;
import com.gitee.apanlh.util.base.ChooseEq;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.MapUtils;
import com.gitee.apanlh.util.dataformat.JsonUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.gitee.apanlh.web.model.vo.RequestVO;
import com.ts.api.common.util.ApiDictUtils;
import com.ts.api.common.util.H5DomainUrlUtils;
import com.ts.api.http.platform.entity.apply.ApiPlatApplyQuXiangHua;
import com.ts.api.http.platform.entity.dataexchange.ApiPlatDataExchangeQuXiangHua;
import com.ts.api.module.api.convert.core.annotation.ApiPlan;
import com.ts.api.module.api.convert.core.annotation.ApiPlanConvertType;
import com.ts.api.module.api.convert.core.entity.ApiApplyParameter;
import com.ts.api.module.api.convert.core.entity.ApiBizStatus;
import com.ts.api.module.api.convert.core.entity.ApiDataExchangeParameter;
import com.ts.api.module.api.convert.core.utils.ApiFieldConverter;
import com.ts.api.module.api.convert.platform.entity.RespPlatformNoticeApply;
import com.ts.api.module.api.convert.platform.entity.RespPlatformPhoneMd5Apply;
import com.ts.api.module.api.convert.platform.entity.RespPlatformPhoneMd5DataExchange;
import com.ts.api.module.api.convert.platform.handler.ApiPlatformPhoneMd5ConvertHandler;
import com.ts.api.module.api.entity.ApiProtocol;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import static com.gitee.apanlh.web.http.HttpContentType.APPLICATION_JSON;

/**
 *  趣享花
 *  飞书链接：https://dcnl8xzfqnp0.feishu.cn/wiki/AtWuwE268ijqzykwBvccT9QGnrf?from=from_copylink   密码：&4t29262
 *
 *  @author 李源聪
 */
@ApiPlan(productId = "162", type = ApiPlanConvertType.PLAT_PHONE_MD5)
public class ApiPlatQuXiangHuaPhoneMd5Convert implements ApiPlatformPhoneMd5ConvertHandler {

    private static final String KEY = "MCXBIjANke";

    @Override
    public Object dataExchange(ApiDataExchangeParameter apiDataExchangeParameter) throws Exception {
        //  撞库流程-默认JSON发送如果需要别的方式，或者需要增加请求头，请看apiDataChangeMessage实体拓展方法
        ApiPlatDataExchangeQuXiangHua apiPlatDataExchange = new ApiPlatDataExchangeQuXiangHua();
        apiDataExchangeParameter.setHttpContentType(APPLICATION_JSON);
        if (ValidParam.isNotEmpty(apiDataExchangeParameter.getPhone())){
            apiPlatDataExchange.setPhoneMd5(apiDataExchangeParameter.getPhoneMd5());
            apiPlatDataExchange.setPhoneMask9(apiDataExchangeParameter.getPhone().substring(0, 9) + "**");
        }else {
            throw new RuntimeException("上游传递手机号为空");
        }
        //  赋值撞库属性
        apiPlatDataExchange.setUserName("浩安星");
        apiPlatDataExchange.setCity(apiDataExchangeParameter.getCity().replace("市", ""));
        apiPlatDataExchange.setAge(apiDataExchangeParameter.getAge());
        apiPlatDataExchange.setOsType("0");
        apiPlatDataExchange.setDeviceId("");
        apiPlatDataExchange.setIp(apiDataExchangeParameter.getIp());
        apiPlatDataExchange.setSource("anxin");
        apiPlatDataExchange.setSystem("anxin");
        apiPlatDataExchange.setChannelMark("anxin");
        apiPlatDataExchange.setAppName("anxin");

        //  撞库字段映射
        dataExchangeFieldMapping(apiDataExchangeParameter, apiPlatDataExchange);

        long currentTimeMillis = System.currentTimeMillis();
        byte[] key = String.format("%s%s", KEY, currentTimeMillis).substring(0, 16).getBytes();
        //  请求实体转换,默认JSON方式，如果FORM方式直接返回实体类，并且设置请求头为FORM表单
        return MapUtils.<String, Object>newHashMap(newMap -> {
            newMap.put("timestamp", currentTimeMillis);
            newMap.put("signs", AES.createEcb(key, AlgorithmPadding.PKCS5).encryptToHex(JsonUtils.toJson(apiPlatDataExchange)));
        });
    }


    @Override
    public Object apply(ApiApplyParameter apiApplyParameter) throws Exception {
        //  进件流程-默认JSON发送如果需要别的方式，或者需要增加请求头，请看apiApplyMessage拓展方法
        ApiPlatApplyQuXiangHua apiPlatApply = new ApiPlatApplyQuXiangHua();
        apiApplyParameter.setHttpContentType(APPLICATION_JSON);

        //  赋值进件属性
        apiPlatApply.setPhone(apiApplyParameter.getPhone());
        apiPlatApply.setUserName(apiApplyParameter.getUserName());

        JSONObject jsonObject = JsonUtils.get(apiApplyParameter.dataExchangeApplyId());

        apiPlatApply.setUuid(jsonObject.getString("uuid"));

        apiPlatApply.setType(jsonObject.getString("type"));

        apiPlatApply.setProductKey(jsonObject.getString("productKey"));

        apiPlatApply.setUrl(H5DomainUrlUtils.createUserProtocolUrl(apiApplyParameter.getProductPlanId(), apiApplyParameter.getPhoneMd5()));

        //  进件字段映射
        applyFieldMapping(apiApplyParameter, apiPlatApply);
        long currentTimeMillis = System.currentTimeMillis();
        byte[] key = String.format("%s%s", KEY, currentTimeMillis).substring(0, 16).getBytes();
        //  请求实体转换,默认JSON方式，如果FORM方式直接返回实体类，并且设置请求头为FORM表单
        return MapUtils.<String, Object>newHashMap(newMap -> {
            newMap.put("timestamp", currentTimeMillis);
            newMap.put("signs", AES.createEcb(key, AlgorithmPadding.PKCS5).encryptToHex(JsonUtils.toJson(apiPlatApply)));
        });
    }

    @Override
    public RespPlatformPhoneMd5Apply respApply(String respJson) throws Exception {
        JSONObject jsonObject = JsonUtils.get(respJson);
        if (jsonObject == null) {
            return RespPlatformPhoneMd5Apply.ofFail();
        }
        if (!Eq.object(jsonObject.getString("result"), "200")) {
            return RespPlatformPhoneMd5Apply.ofFail();
        }
        return RespPlatformPhoneMd5Apply.ofSuc();
    }

    /**
     *   撞库字段转换映射
     *   1.撞库字段转换(不需要的自行删除)
     *   2.第一个形参值是我方值, 第二个形参值,是对方文档值,必须注意参数类型对应, end指的是如果都不存在给默认值)
     */
    private void dataExchangeFieldMapping(ApiDataExchangeParameter apiDataExchangeParameter, ApiPlatDataExchangeQuXiangHua apiPlatDataExchange) {
        /*
           我方字典-贷款金额
           1.3万以下
           2.5万-10万
           3.10万-20万
           4.20万以上
           如果对方文档需要"带单位"如:3万，5万,使用apiFieldConverter.getLoanAmountUnit
           如果对方文档需要"数字形式"使用apiFieldConverter.getLoanAmountInt(),返回30000，50000
         */
        String loanAmount = ChooseEq.create(apiDataExchangeParameter.getLoanAmount())
                .when("1", "2")
                .when("2", "3")
                .when("3", "4")
                .when("4", "5")
                .end();
        apiPlatDataExchange.setLoanAmount(loanAmount);

        //  性别-要获取中文性别（男/女）使用apiFieldConverter.getSexText
        String sex = ChooseEq.create(apiDataExchangeParameter.getSex())
                .when("0", "1")
                .when("1", "2")
                .end();
        apiPlatDataExchange.setSex(sex);

        /*
           我方字典-芝麻分
           1.600分以下
           2.600~649分
           3.650~699分
           4.700分以上
           如果对方需要"分值形式"如:650，700,使用apiFieldConverter.getSesameCreditNumber/getSesameCreditStr
           如果对方要"文字形式"如:600分以下,600~649分,使用apiFieldConverter.getSesameCreditText
         */
        String sesameCredit = ChooseEq.create(apiDataExchangeParameter.getSesameCredit())
                .when("1", "5")
                .when("2", "5")
                .when("3", "6")
                .when("4", "4")
                .end();
        apiPlatDataExchange.setSesameCredit(sesameCredit);

        /*
           我方字典-车辆情况
           1.无车产
           2.有车不抵押
           3.有车可抵押
           4.有车
           如果对方文档是需要返回"0"和"1" 使用:apiFieldConverter.hasCarInfoToNumber
           如果对方文档是需要返回"有"和"无",使用:apiFieldConverter.hasCarInfoToStr
         */
        String carInfo = ChooseEq.create(apiDataExchangeParameter.getCarInfo())
                .when("1", "1")
                .when("2", "2")
                .when("3", "2")
                .when("4", "2")
                .end();
        apiPlatDataExchange.setCarInfo(carInfo);

        /*
           我方字典-职业
           1.上班族
           2.自由职业
           3.企业主（有营业执照）
           4.公务员或事业单位
           如果对方需要"文字形式"如:上班族/公务员或事业单位,使用apiFieldConverter.getCareerText
           如果对方需要"有无职业或者是否有工作"如:有/无，使用使用apiFieldConverter.hasCareerToStr
           如果对方需要"有无职业或者是否有工作"如:0/1，使用使用apiFieldConverter.hasCareerToNumber
         */
        String career = ChooseEq.create(apiDataExchangeParameter.getCareer())
                .when("1", "1")
                .when("2", "2")
                .when("3", "3")
                .when("4", "1")
                .when("5", "2")
                .end();
        apiPlatDataExchange.setCareer(career);

        /*
          我方字典-月收入
          1.1000-3000
          2.3000-8000
          3.8000~15000
          4.15000~30000
          5.30000以上
          如果对方需要"数值形式"如:3000,5000,使用apiFieldConverter.getMonthlySalaryNumber
          如果对方需要"有无月收入"如:有/无，使用使用apiFieldConverter.hasMonthlySalaryToStr
          如果对方需要"有无月收入"如:0/1，使用使用apiFieldConverter.hasMonthlySalaryToNumber
        */
        String monthlySalary = ChooseEq.create(apiDataExchangeParameter.getMonthlySalary())
                .when("1", "1")
                .when("2", "2")
                .when("3", "2")
                .when("4", "5")
                .when("5", "6")
                .end();
        apiPlatDataExchange.setMonthlySalary(monthlySalary);

        String bizLicenseYear = ChooseEq.create(apiDataExchangeParameter.getBizLicenseYear())
                .when("1", "1")
                .when("2", "1")
                .when("3", "2")
                .when("4", "3")
                .end();
        apiPlatDataExchange.setBizLicenseYear(bizLicenseYear);

        /*
          我方字典-房产情况
          1.无房产
          2.有房不抵押
          3.有房可抵押
          4.有房产
          5.有按揭房产
          6.有全款房产
          如果对方需要"有无月收入"如:有/无，使用使用apiFieldConverter.hasRealEstateInfoToStr
          如果对方需要"有无月收入"如:0/1，使用使用apiFieldConverter.hasRealEstateInfoToNumber
        */
        String realEstateInfo = ChooseEq.create(apiDataExchangeParameter.getRealEstateInfo())
                .when("1", "1")
                .when("2", "5")
                .when("3", "5")
                .when("4", "5")
                .when("5", "5")
                .when("6", "5")
                .end();
        apiPlatDataExchange.setRealEstateInfo(realEstateInfo);

        /*
          我方字典-公积金
          1.无公积金
          2.缴纳6个月以下
          3.缴纳6个月以上
          4.有公积金
          如果对方只需要"有/无"使用:apiFieldConverter.hasProvidentFundToStr
          如果对方只需要"0/1"使用:apiFieldConverter.hasProvidentFundToNumber
        */
        String providentFund = ChooseEq.create(apiDataExchangeParameter.getProvidentFund())
                .when("1", "1")
                .when("2", "2")
                .when("3", "3")
                .when("4", "2")
                .end();
        apiPlatDataExchange.setProvidentFund(providentFund);

        /*
          我方字典-社保缴纳
          1.无社保
          2.缴纳6个月以下
          3.缴纳6个月以上
          4.有社保
          如果对方需要"有无社保情况"如:有/无，使用使用apiFieldConverter.hasSocialSecurityToStr
          如果对方需要"有无社保情况"如:0/1，使用使用apiFieldConverter.hasSocialSecurityToNumber
        */
        String socialSecurity = ChooseEq.create(apiDataExchangeParameter.getSocialSecurity())
                .when("1", "1")
                .when("2", "2")
                .when("3", "3")
                .when("4", "2")
                .end();
        apiPlatDataExchange.setSocialSecurity(socialSecurity);

       /*
            我方字典-保险保单
            1.无保险保单
            2.缴纳未满1年
            3.缴纳1年以上
            4.有保险保单
            如果对方只需要"有/无"使用:apiFieldConverter.hasInsurancePolicyToStr
            如果对方只需要"0/1"使用:apiFieldConverter.hasInsurancePolicyToNumber
        */
        String insurancePolicy = ChooseEq.create(apiDataExchangeParameter.getInsurancePolicy())
                .when("1", "1")
                .when("2", "2")
                .when("3", "3")
                .when("4", "2")
                .end();
        apiPlatDataExchange.setInsurancePolicy(insurancePolicy);

        /*
            我方字典-花呗额度
            1.无额度
            2.3千以下
            3.3千-1万
            4.1万-3万
            5.3万以上
            如果对方文档需要"文字类型"如:无额度,3千以下,使用使用apiFieldConverter.getHbLimitText
         */
        String hbLimit = ChooseEq.create(apiDataExchangeParameter.getHbLimit())
                .when("1", "1")
                .when("2", "2")
                .when("3", "3")
                .when("4", "4")
                .when("5", "4")
                .end();
        apiPlatDataExchange.setHbLimit(hbLimit);

        /*
          我方字典-信用卡额度
          1.无信用卡
          2.3千以下
          3.3千-1万
          4.1-3万
          5.3万以上
          6.有信用卡
          如果对方只需要"有/无"使用:apiFieldConverter.hasCreditLimitToStr
          如果对方只需要"0/1"使用:apiFieldConverter.hasCreditLimitToNumber
        */
        String creditLimit = ChooseEq.create(apiDataExchangeParameter.getCreditLimit())
                .when("1", "1")
                .when("2", "2")
                .when("3", "2")
                .when("4", "3")
                .when("5", "4")
                .when("6", "2")
                .end();
        apiPlatDataExchange.setCreditLimit(creditLimit);

        /*
           我方字典-信用情况（逾期）
           1.无逾期
           2.当前有逾期
           3.一年以内无逾期
           如果对方文档是需要返回"0"和"1" 使用:apiFieldConverter.hasOverdueToNumber
           如果对方文档是需要返回"有"和"无",使用:apiFieldConverter.hasOverdueToStr方法
         */
        String overdue = ChooseEq.create(apiDataExchangeParameter.getOverdue())
                .when("1", "1")
                .when("2", "3")
                .when("3", "2")
                .end();
        apiPlatDataExchange.setOverdue(overdue);

        /*
          我方字典-学历
          1.初中及以下
          2.中专
          3.高中
          4.大专
          5.本科
          6.研究生及以上
        */
        String educationAttainment = ChooseEq.create(apiDataExchangeParameter.getEducationAttainment())
                .when("1", "1")
                .when("2", "1")
                .when("3", "1")
                .when("4", "2")
                .when("5", "3")
                .when("6", "4")
                .end();
        apiPlatDataExchange.setEducationAttainment(educationAttainment);

       /*
          我方字典-工资发放形式/银行代发/打卡方式
          1.银行代发打卡
          2.现金收入
          3.个人转账
          如果对方只需要"银行代发-有/无"使用:apiFieldConverter.hasSalaryBankToStr
          如果对方只需要"银行代发-是/否"使用:apiFieldConverter.hasSalaryBankChooseToStr
          如果对方只需要"银行代发-0/1"使用:apiFieldConverter.hasSalaryBankToNumber
        */
        String salaryPayMethod = ChooseEq.create(apiDataExchangeParameter.getSalaryPayMethod())
                .when("1", "1")
                .when("2", "2")
                .when("3", "3")
                .end();
        apiPlatDataExchange.setSalaryPayMethod(salaryPayMethod);

    }

    /**
     *   字段转换映射
     *   1.表单信息字段转换(不需要的自行删除)
     *   2.第一个形参值是我方值, 第二个形参值,是对方文档值,必须注意参数类型对应, end指的是如果都不存在给默认值)
     */
    private void applyFieldMapping(ApiApplyParameter apiApplyParameter, ApiPlatApplyQuXiangHua apiPlatApply) {
        //  获取封装字段转换器
        ApiFieldConverter apiFieldConverter = ApiFieldConverter.create(apiApplyParameter);

        //  获取年龄-自行根据文档中的类型
        Integer ageInt = apiFieldConverter.getAgeInt();
        String age = apiFieldConverter.getAge();

        //  城市/默认不带市
        String sourceCity = ApiDictUtils.getAreaNameByName(apiApplyParameter.getCity());

    }

    @Override
    public RespPlatformPhoneMd5DataExchange respDataExchange(String respJson) {
        //  撞库返回响应体判断
        JSONObject jsonObject = JsonUtils.get(respJson);
        if (jsonObject == null) {
            return RespPlatformPhoneMd5DataExchange.ofFail();
        }
        if (!Eq.object(jsonObject.getString("result"), "200")) {
            return RespPlatformPhoneMd5DataExchange.ofFail();
        }

        JSONObject respBody = JsonUtils.get(respJson);

        //  获取属性值
        JSONObject resData = JsonUtils.get(respJson).getJSONObject("data");
        String timestamp = resData.getString("timestamp");
        byte[] key = String.format("%s%s", KEY, timestamp).substring(0, 16).getBytes();
        String signs1 = resData.getString("signs");
        JSONObject signs = JsonUtils.get(AES.createEcb(key, AlgorithmPadding.PKCS5).decryptFromHexStr(signs1));
        BigDecimal price = signs.getBigDecimal("price");
        String logo = signs.getString("logoUrl");
        String companyName = signs.getString("companyName");
        String productName = signs.getString("productName");

        //  返回转换内容
        RespPlatformPhoneMd5DataExchange result = RespPlatformPhoneMd5DataExchange.ofSuc();


        result.setPrice(price);
        result.setLogoPath(logo);
        result.setDisplayName(companyName);
        result.setProductName(productName);

        List<ApiProtocol> protocolList = CollUtils.newArrayList(newList -> {
            ApiProtocol protocol = new ApiProtocol();
            protocol.setProtocolName("个人隐私协议");
            protocol.setProtocolUrl(signs.getString("privateUrl"));
            newList.add(protocol);
            protocol.setProtocolName("助贷服务协议");
            protocol.setProtocolUrl(signs.getString("serviceUrl"));
            newList.add(protocol);
        });

        result.setProtocolList(protocolList);

        Map<String, Object> tmpData = MapUtils.newHashMap(newMap -> {
            newMap.put("uuid", signs.getString("uuid"));
            newMap.put("productKey", signs.getString("productKey"));
            newMap.put("type", signs.getString("type"));
        });
        result.setApplyId(JsonUtils.toJson(tmpData));
        return result;
    }

    @Override
    public RespPlatformNoticeApply parseApplyNotice(RequestVO requestVO) {
        JSONObject jsonObject = JsonUtils.get(requestVO.getBody());
        return null;
    }

    @Override
    public Map<String, Object> respApplyNotice(ApiBizStatus apiBizStatus) {
        return null;
    }
}
